package test

import com.gitee.ixtf.guice.Jguice
import com.gitee.ixtf.vertx.guice.GraphqlGuice
import com.gitee.ixtf.vertx.guice.RestfulGuice
import com.gitee.ixtf.vertx.guice.VertxGuice
import com.google.inject.Provides
import com.google.inject.Singleton
import io.opentelemetry.api.GlobalOpenTelemetry
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
import io.opentelemetry.context.propagation.ContextPropagators
import io.opentelemetry.sdk.OpenTelemetrySdk
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk
import io.opentelemetry.sdk.trace.SdkTracerProvider
import io.vertx.core.*
import io.vertx.ext.auth.oauth2.OAuth2Auth
import io.vertx.ext.auth.oauth2.providers.OpenIDConnectAuth
import io.vertx.ext.web.common.WebEnvironment.SYSTEM_PROPERTY_NAME
import io.vertx.kotlin.coroutines.coAwait
import io.vertx.kotlin.ext.auth.oauth2.oAuth2OptionsOf
import io.vertx.tracing.opentelemetry.OpenTelemetryOptions
import kotlin.system.exitProcess
import kotlinx.coroutines.runBlocking
import test.resource.MutationResource
import test.resource.RestfulResource
import test.verticle.TestVerticle

fun main(args: Array<String>) {
  System.setProperty("ixtf.api.service", "test")
  System.setProperty("ixtf.api.port", "30000")
  System.setProperty("otel.service.name", "test")
  //  System.setProperty("otel.metrics.exporter", "none")
//  System.setProperty("otel.traces.exporter", "logging")
//  System.setProperty("otel.metrics.exporter", "logging")
//  System.setProperty("otel.logs.exporter", "logging")
  System.setProperty("otel.exporter.otlp.endpoint", "http://172.10.10.2:4317")
  System.setProperty(SYSTEM_PROPERTY_NAME, "dev")
  TestVertx().dispatch(args)
}

private class TestVertx : Launcher() {
  override fun getMainVerticle(): String = TestVerticle::class.java.name

  override fun beforeStartingVertx(options: VertxOptions) {
    super.beforeStartingVertx(options)
    with(options) {
      // maxEventLoopExecuteTime = 1.days.inWholeNanoseconds
      preferNativeTransport = true
      tracingOptions = OpenTelemetryOptions()

//      val sdkTracerProvider = SdkTracerProvider.builder().build()
//      val openTelemetry =
//          OpenTelemetrySdk.builder()
//              .setTracerProvider(sdkTracerProvider)
//              .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
//              .buildAndRegisterGlobal()
//      tracingOptions = OpenTelemetryOptions(openTelemetry)

       tracingOptions =
       OpenTelemetryOptions(AutoConfiguredOpenTelemetrySdk.initialize().openTelemetrySdk)
    }
  }

  override fun afterStartingVertx(vertx: Vertx) {
    super.afterStartingVertx(vertx)
    Runtime.getRuntime().addShutdownHook(Thread { runBlocking { vertx.close().coAwait() } })
    Jguice.init(TestVertxModule(vertx))

    println(GlobalOpenTelemetry.get())
    // vertx.deployVerticle(TestQueueVerticle)
  }

  override fun handleDeployFailed(
      vertx: Vertx,
      mainVerticle: String?,
      deploymentOptions: DeploymentOptions?,
      cause: Throwable?,
  ) {
    cause?.printStackTrace()
    exitProcess(1)
  }
}

class TestVertxModule(vertx: Vertx) : VertxGuice(vertx) {
  override fun configure() {
    super.configure()
    install(GraphqlGuice(MutationResource::class.java))
    install(RestfulGuice(RestfulResource::class.java))
  }

  @Singleton
  @Provides
  private fun OAuth2Auth(vertx: Vertx): Future<OAuth2Auth> =
      OpenIDConnectAuth.discover(
          vertx,
          oAuth2OptionsOf(
              site = "https://sso.mpai.medipath.com.cn/auth/realms/mpai",
              clientID = "api",
              clientSecret = "api"))
}
